package com.qujia.station.service.impl;

import com.qujia.common.core.domain.model.LoginUser;
import com.qujia.common.exception.CustomException;
import com.qujia.common.utils.SecurityUtils;
import com.qujia.common.utils.StringUtils;
import com.qujia.station.domain.Commodity;
import com.qujia.station.domain.NonOilCategory;
import com.qujia.station.mapper.CommodityMapper;
import com.qujia.station.mapper.NonOilCategoryMapper;
import com.qujia.station.service.INonOilCategoryService;
import com.qujia.station.utils.RandomCharacterUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;


/**
 * (NonOilCategory)表服务实现类
 *
 * @author makejava
 * @since 2023-08-14 17:29:16
 */
@Service("nonOilCategoryService")
@Slf4j
public class NonOilCategoryServiceImpl implements INonOilCategoryService {
    @Resource
    private NonOilCategoryMapper nonOilCategoryMapper;

    @Resource
    private CommodityMapper commodityMapper;


    @Override
    public NonOilCategory queryById(Long categoryId) {
        return nonOilCategoryMapper.queryById(categoryId);
    }

    @Override
    public String queryCategoryName(Long categoryId,List<NonOilCategory> list) {
        String categoryName="";
        //NonOilCategory category = nonOilCategoryMapper.queryById(categoryId);
        NonOilCategory category=null;
        for (NonOilCategory nonOilCategory : list) {
            if(categoryId.equals(nonOilCategory.getCategoryId())){
                category=nonOilCategory;
                break;
            }
        }
        if(category==null||category.getPid()==NonOilCategory.TOP_CATEGORY_ID){
            return "";
        }
        if(categoryName!=null){
            Long pid = category.getPid();
            categoryName=category.getCategoryName();
            String name=queryCategoryName(pid,list);
            if(StringUtils.isNotEmpty(name)){
                categoryName=name+"/"+categoryName;
            }
        }
        return categoryName;
    }

    @Override
    public List<Long> getChildIds(Long categoryId) {
        NonOilCategory query=new NonOilCategory();
        query.setPid(categoryId);
        List<NonOilCategory> list = nonOilCategoryMapper.selectChildren(query);
        List<Long> childIds = list.stream().map(NonOilCategory::getCategoryId).collect(Collectors.toList());
        if(list.size()>0){
            for (NonOilCategory nonOilCategory : list) {
                Long id = nonOilCategory.getCategoryId();
                List<Long> childIds2 = getChildIds(id);
                childIds.addAll(childIds2);
            }
        }
        return childIds;
    }


    public NonOilCategory getNonOilCategoryTree (NonOilCategory nonOilCategory){
        List<NonOilCategory> categoryList=nonOilCategoryMapper.selectAll(nonOilCategory);
        if(CollectionUtils.isEmpty(categoryList)){
            return null;
        }
        for (NonOilCategory category : categoryList) {
            category.setIsCommodity("0"); // 类目标记
        }
        Map<Long, List<NonOilCategory>> collect = categoryList.stream().collect(Collectors.groupingBy(n->n.getPid()));
        NonOilCategory topCategory = collect.get(NonOilCategory.TOP_CATEGORY_ID).get(0);
        List<NonOilCategory> tree = listToTree(collect, topCategory);
        topCategory.setChildren(tree);
        SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");

        String categoryName = nonOilCategory.getCategoryName();
        Date beginTime = nonOilCategory.getBeginTime();
        Date endTime = nonOilCategory.getEndTime();

        if(StringUtils.isNotEmpty(categoryName)||beginTime!=null||endTime!=null){
            NonOilCategory p=new NonOilCategory();
            List<NonOilCategory> list=new ArrayList<>();
            list.add(topCategory);
            p.setChildren(list);
            p=exclude(p,topCategory,beginTime,endTime,categoryName);
            if(p.getChildren().size()>0){
                return p.getChildren().get(0);
            }else{
                return new NonOilCategory();
            }

        }else{
            return topCategory;
        }

    }

    public NonOilCategory exclude(NonOilCategory parentCategory ,NonOilCategory nonOilCategory,Date beginTime,Date endTime,String categoryName){
        boolean flag = check(nonOilCategory, beginTime, endTime, categoryName);
        if(nonOilCategory.getChildren()==null||nonOilCategory.getChildren().size()==0){
            //最底层
            if(!flag){
                //最底层且不满足条件则删除该元素
                List<NonOilCategory> children = parentCategory.getChildren();
                if(children!=null&&children.size()>0){
                    for (NonOilCategory category : children) {
                        if(category.getCategoryId().equals(nonOilCategory.getCategoryId())){
                            children.remove(category);
                            break;
                        }
                    }
                }
                return parentCategory;
            }
        }else{
            //非最底层
            //如果满足条件直接返回
            if(flag){
                return parentCategory;
            }else{
                //不满足条件则判断之后的节点是否符合
                List<NonOilCategory> children = nonOilCategory.getChildren();
                if(children!=null&&children.size()>0){
                    int total=children.size();
                    for (int i = 0; i < children.size(); i++) {
                        NonOilCategory child=children.get(i);
                        nonOilCategory=exclude(nonOilCategory,child,beginTime,endTime,categoryName);
                        i=i-(total-children.size());
                        total=children.size();
                    }

                    List<NonOilCategory> list = nonOilCategory.getChildren();
                    if(list==null||list.size()==0){
                        for (NonOilCategory category : parentCategory.getChildren()) {
                            if(category.getCategoryId().equals(nonOilCategory.getCategoryId())){
                                parentCategory.getChildren().remove(category);
                                break;
                            }
                        }
                    }
                }
            }
        }
        return parentCategory;
    }

    public boolean check(NonOilCategory nonOilCategory,Date beginTime,Date endTime,String categoryName){
//都满足条件为true 有不符合条件的为false
        boolean flag=true;
        if(categoryName!=null&&!categoryName.equals("")){
            if(nonOilCategory.getCategoryName().contains(categoryName)){
                flag=flag&&true;
            }else{
                flag=flag&&false;
            }
        }
        long createTime = nonOilCategory.getCreateTime().getTime();
        if(beginTime!=null){
            if(createTime>=beginTime.getTime()){
                flag=flag&& true;
            }else{
                flag=flag&& false;
            }
        }
        if(endTime!=null){
            if(createTime<=endTime.getTime()){
                flag=flag&& true;
            }else{
                flag=flag&& false;
            }
        }
        return flag;
    }


    public List<NonOilCategory>  listToTree(Map<Long, List<NonOilCategory>> collect,NonOilCategory nonOilCategory){
        List<NonOilCategory> children = collect.get(nonOilCategory.getCategoryId());
        if(children==null){
            children=new ArrayList<>();
        }
        nonOilCategory.setChildren(children);
        if(children!=null&&children.size()>0){
            for (NonOilCategory oilCategory : children) {
                List<NonOilCategory> tree = listToTree(collect, oilCategory);
                oilCategory.setChildren(tree);

            }
        }

        return children;
    }


    @Override
    public int insertCategory(NonOilCategory nonOilCategory) {
        LoginUser currentUser = SecurityUtils.getLoginUser();
        nonOilCategory.setCreateUser(currentUser.getUser().getUserId());
        nonOilCategory.setCreateTime(new Date());
        Long pid = nonOilCategory.getPid();
        NonOilCategory p = nonOilCategoryMapper.queryById(pid);
        if(p.getLevel()>=4){
            throw new CustomException("分类不能超过三级");
        }
        nonOilCategory.setLevel(p.getLevel()+1);
        //同级名称相同
        List<NonOilCategory> list=nonOilCategoryMapper.query(nonOilCategory);
        if(list.size()>0){
            throw new CustomException("同级已存在相同的分类");
        }

        // 生成分类编码
        return createCategoryCode(nonOilCategory);
    }

    private int createCategoryCode(NonOilCategory nonOilCategory){
        int i = 0;
        synchronized (this){
            String code = null;
            boolean flag = true;
            // 校验 重复
            while (flag) {
                code = RandomCharacterUtils.generateRandomCharacter();
                NonOilCategory result = nonOilCategoryMapper.selectByCategoryCode(code);
                if(Objects.isNull(result)){
                    flag = false; // 终止循环
                }
            }
            nonOilCategory.setCategoryCode(code);
            i = nonOilCategoryMapper.insertCategory(nonOilCategory);
        }
        return i;
    }

    @Override
    public int update(NonOilCategory nonOilCategory) {
        LoginUser currentUser = SecurityUtils.getLoginUser();
        nonOilCategory.setUpdateTime(new Date());
        nonOilCategory.setUpdateUser(currentUser.getUser().getUserId());
        Long pid = nonOilCategory.getPid();
        if(pid!=null){
            NonOilCategory p = nonOilCategoryMapper.queryById(pid);
            List<Long> childIds = getChildIds(nonOilCategory.getCategoryId());
            if(childIds.contains(pid)){
                throw new CustomException("不能更新所属分类为自己的子分类");
            }
            if(nonOilCategory.getCategoryId().equals(nonOilCategory.getPid())){
                throw new CustomException("父分类不能为自己");
            }
            if(p.getLevel()>=4){
                throw new CustomException("分类不能超过三级");
            }
            nonOilCategory.setLevel(p.getLevel()+1);
        }
        return nonOilCategoryMapper.update(nonOilCategory);
    }

    @Override
    public int deleteById(Long categoryId) {

        return nonOilCategoryMapper.deleteById(categoryId);
    }

    @Override
    public int delete(List<Long> categoryIds) {
        List<Long> tempList=new ArrayList<>();
        for (Long categoryId : categoryIds) {
            List<Long> childIds = getChildIds(categoryId);
            tempList.addAll(childIds);
        }
        categoryIds.addAll(tempList);

        Commodity commodity=new Commodity();
        commodity.setCategoryIds(categoryIds);
        List<Commodity> query = commodityMapper.query(commodity);

        if(query.size()>0){
            throw new CustomException("删除的分类中存在被商品列表使用的分类");
        }
        if(categoryIds!=null&&categoryIds.size()>0){
            return nonOilCategoryMapper.deleteByIds(categoryIds);
        }

        return 0;
    }

    @Override
    public List<NonOilCategory> selectAll(NonOilCategory nonOilCategory) {
        return nonOilCategoryMapper.selectAll(nonOilCategory);
    }

    @Override
    public NonOilCategory getNonOilCategoryTreeAndCommodity(NonOilCategory nonOilCategory) {
        NonOilCategory nonOilCategoryTree = getNonOilCategoryTree(nonOilCategory);
        List<NonOilCategory> children = nonOilCategoryTree.getChildren();
        if(CollectionUtils.isEmpty(children)){
            return nonOilCategoryTree;
        }
        for (NonOilCategory child : children) {
//            if(CollectionUtils.isEmpty(child.getChildren())){
//                Commodity req = new Commodity();
//                req.setCategoryId(child.getCategoryId());
//                req.setStationId(nonOilCategory.getStationId());
//                List<Commodity> commodities = commodityMapper.selectCommodityList(req);
//                List<NonOilCategory> nonOilCategoryList = new ArrayList<>();
//                if(CollectionUtils.isNotEmpty(commodities)){
//                    for (Commodity commodity : commodities) {
//                        NonOilCategory category = new NonOilCategory();
//                        category.setCategoryId(-commodity.getCommodityId());
//                        category.setCategoryName(commodity.getCommodityName());
//                        category.setPid(commodity.getCategoryId());
//                        category.setCommodity(commodity);
//                        nonOilCategoryList.add(category);
//                    }
//                }
//                child.setChildren(nonOilCategoryList);
//            }
            recursionTree(child,nonOilCategory);
        }
        return nonOilCategoryTree;
    }

    // 递归 遍历 目录树
    private void recursionTree(NonOilCategory children, NonOilCategory nonOilCategory){
        if(CollectionUtils.isNotEmpty(children.getChildren()) && "0".equals(children.getIsCommodity())){
            List<NonOilCategory> nonOilCategoryList = children.getChildren();
            for (NonOilCategory child : nonOilCategoryList) {
                recursionTree(child,nonOilCategory);
            }
            addCommodity(children,nonOilCategory);
        }else {
            addCommodity(children,nonOilCategory);
        }
    }

    private void addCommodity(NonOilCategory children, NonOilCategory nonOilCategory){
        Commodity req = new Commodity();
        req.setCategoryId(children.getCategoryId());
        req.setStationId(nonOilCategory.getStationId());
        List<Commodity> commodities = commodityMapper.selectCommodityList(req);
        List<NonOilCategory> nonOilCategoryList = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(commodities)){
            for (Commodity commodity : commodities) {
                NonOilCategory category = new NonOilCategory();
                category.setCategoryId(-commodity.getCommodityId());
                category.setCategoryName(commodity.getCommodityName());
                category.setPid(commodity.getCategoryId());
                commodity.setCategoryName(children.getCategoryName());
                category.setCommodity(commodity);
                category.setIsCommodity("1"); //商品
                nonOilCategoryList.add(category);
            }
        }

        if(CollectionUtils.isEmpty(children.getChildren())){
            children.setChildren(nonOilCategoryList);
        } else {
            List<NonOilCategory> nonOilCategories = children.getChildren();
            nonOilCategories.addAll(nonOilCategoryList);
            children.setChildren(nonOilCategories);
        }
    }
}
